<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Immediately Invoked Function Expression (自调用函数表达式) </title>
</head>
<div>
    为啥要函数自调用?
    <ol>
        <li>有些情况下, 只想定义完直接用, 不需要处理其他的</li>
        <li>引入框架, 不可能还要初始化, 引入即用</li>
    </ol>
</div>


<body>


<script>

    /**
     * 第 1 种：函数的声明 需要函数名
     * */
    function func() {
        console.log("我是第一种定义函数的方式");
    }

    /**
     *  第 2 种：函数表达式(匿名函数) 需要定义变量接收
     * */
    const aa = function () {
        console.log("我是第二种定义函数的方式");
    };



    //jq
    let $ = (
        function () {
            console.log("hello jQuery");
        }
    );


    //调用
    func();

    //调用
    aa();

    $();


    /*
      我能否直接 定义完毕后直接加 ()  来调用呢? 下面的代码在编辑器中报错 Uncaught SyntaxError: Unexpected token ')'
     * function func1() {
                    console.log(111);
           }();
     because  上面代码被当成了函数声明，而不是一个函数表达式，让后面的"();"  变得孤立,从而产生语法错误。
     我们要解决的就是让 function func1() {console.log(111);} 是一个函数表达式，而不是函数声明语句。
     */



  //  方法1(推荐)： 定义完后 加 () 执行, 并把整个函数用括号包起来(jslint推荐的写法)

    // 没有参数的情况
    (function () {
        console.log(111);
    }());

    // 有参数的情况
    (function (a ,  b ) {
        // 函数体
        console.log(a + b);
    }(12,34 ));

    //方法2 function 外面加括号 ,  再加() 执行
    //没有参数的情况
    (function () {
        console.log(222);
    })();

    //有参数的情况
    (function ( a,  b ) {
        console.log(a + b);     //函数体
    })(11, 22);

    //方法3：最前面和最后加上中括号
    //没有参数的情况
    [function () {
        console.log(333);
    }()];

    //有参数的情况
    [function (a, b) {
        console.log(a + b);     //函数体
    }(11, 22)];


     //方法4： function前面加运算符 ，常用的是!、-、+
    //没有参数的情况
    !function () {
        console.log(444);
    }();

    //有参数的情况
    !function (a, b) {
        console.log(a + b);     //函数体
    }(11, 22);


    //方法5： function前面加void
    //没有参数的情况
    void function () {
        console.log(555);
    }();

    //有参数的情况
    void function (a, b) {
        console.log(a + b);     //函数体
    }(11, 22);


</script>


</body>
</html>
